package api

import (
	"bee/pkg/app"
	"bee/pkg/e"
	"bee/pkg/logging"
	"bee/pkg/util"
	"bee/service/env_service"
	"bee/service/order_service"
	"github.com/gin-gonic/gin"
	"github.com/srlemon/gen-id/generator"
	"net/http"
	"strconv"
	"time"
)

type AddOrderForm struct {
	UserType int `form:"user_type" valid:"Range(1,2)"`
	OrderType int `form:"order_type"`
	InvoiceType int `form:"invoice_type"`
	CashNum string `form:"cash_num"`
	CouponNum string `form:"coupon_num"`
	Namespace string `form:"namespace" valid:"Required"`
}

var (
	g = new(generator.GeneratorData)
)

func CreateOrder(c *gin.Context) {

	traceId := util.GetTraceID(c)
	fullName := "bee-autotest-" + strconv.Itoa(int(time.Now().Unix()))
	bankId := g.GeneratorBankID()
	receiverMobile := g.GeneratorPhone()
	receiverEmail := g.GeneratorEmail()

	var (
		appG = app.Gin{C: c}
		form AddOrderForm
	)

	httpCode, errCode := app.BindAndValid(c, &form, traceId)
	if errCode != e.SUCCESS {
		appG.Response(httpCode, errCode, traceId, nil)
		return
	}

	envService := env_service.Env{
		Namespace: form.Namespace,
		TraceId:   traceId,
	}
	envs, envsErr := envService.GetAllAppEnv()
	if envsErr != nil {
		appG.Response(http.StatusInternalServerError, e.ERROR, traceId, nil)
		return
	}

	orderService := order_service.Order{
		UserType:    form.UserType,
		TraceId: traceId,
		CashNum: form.CashNum,
		CouponNum: form.CouponNum,
	}

	bossHost := util.GetAppEnv(envs, "boss", "app_domain")
	token, tokenErr := orderService.GetBossToken(bossHost)
	if tokenErr != nil {
		appG.Response(http.StatusInternalServerError, e.ERROR, traceId, nil)
		return
	}

	orderService.FullName = fullName
	ccHost := util.GetAppEnv(envs, "cc", "app_domain")
	customerId, customerErr := orderService.CreateCustomer(ccHost)
	if customerErr != nil {
		appG.Response(http.StatusInternalServerError, e.ERROR, traceId, nil)
		return
	}

	orderService.Token = token
	orderService.CustomerId = customerId
	orderService.BankID = bankId

	opcHost := util.GetAppEnv(envs, "opc", "app_domain")
	identityId, accountId, accountErr := orderService.CreateAccount(opcHost)
	if accountErr != nil {
		appG.Response(http.StatusInternalServerError, e.ERROR, traceId, nil)
		return
	}

	ng2Host := util.GetAppEnv(envs, "nbgl2", "app_domain")
	jsessionid := util.GetAppEnv(envs, "nbgl2", "cookie")
	cashErr := orderService.CreateCash(ng2Host, jsessionid)
	if cashErr != nil {
		appG.Response(http.StatusInternalServerError, e.ERROR, traceId, nil)
		return
	}

	remittanceId, remittanceIdErr := orderService.QueryRemittance(opcHost)
	if remittanceIdErr != nil {
		logging.ZapLogger.Infow("查询流水错误", "数据", remittanceIdErr, "traceId", traceId)
		appG.Response(http.StatusInternalServerError, e.ERROR, traceId, nil)
		return
	}

	orderService.ReceiverEmail = receiverEmail
	orderService.ReceiverMobile = receiverMobile
	orderService.RemittanceId = remittanceId
	orderService.AccountId = accountId
	orderService.IdentityId = identityId

	cashDepositId, depositIdErr := orderService.CreateDepositBill("cash", opcHost)
	if depositIdErr != nil {
		appG.Response(http.StatusInternalServerError, e.ERROR, traceId, nil)
		return
	}

	couponDepositId, couponDepositIdErr := orderService.CreateDepositBill("coupon", opcHost)
	if couponDepositIdErr != nil {
		appG.Response(http.StatusInternalServerError, e.ERROR, traceId, nil)
		return
	}

	_, noAuditCouponDepositIdErr := orderService.CreateDepositBill("coupon", opcHost)
	if noAuditCouponDepositIdErr != nil {
		appG.Response(http.StatusInternalServerError, e.ERROR, traceId, nil)
		return
	}

	orderService.CashDepositId = cashDepositId
	orderService.CouponDepositId = couponDepositId

	orderService.OrderType = form.OrderType

	otcProHost := util.GetAppEnv(envs,"otcpro", "app_domain")
	_, ordinaryErr := orderService.CreateOrdinaryOrder(otcProHost)
	if ordinaryErr != nil {
		appG.Response(http.StatusInternalServerError, e.ERROR, traceId, nil)
		return
	}

	_, settleErr := orderService.CreateSettleOrder(otcProHost)
	if settleErr != nil {
		appG.Response(http.StatusInternalServerError, e.ERROR, traceId, nil)
		return
	}

	auditErr := orderService.Audit(opcHost)
	if auditErr != nil {
		appG.Response(http.StatusInternalServerError, e.ERROR, traceId, nil)
		return
	}

	appG.Response(httpCode, errCode, traceId, orderService)

}